import React, { lazy, Suspense, useEffect } from "react";
import { Navigate, Outlet } from "react-router-dom";
import PropTypes from "prop-types";
import ErrorPage, { NotFound } from "@/pages/error";
import { Skeleton } from "antd";
import BrowserRouter from "./BrowserRouter";

import { useHistoryLocation } from "@/hooks";

const lazyImport = (path) => lazy(() => import(/* @vite-ignore */ `../${path}`));

const ROUTER_CATALOG_COMPONENT = "outlet";
export const Layout = lazyImport("layout");

export const layoutRouter = {
  path: "/",
  element: <Layout />,
  errorElement: <ErrorPage />,
  handle: { title: "首页", icon: "HomeOutlined" },
};

export const SpinFallback = () => {
  const [fromLocation, toLocation] = useHistoryLocation();

  useEffect(() => {
    browserRouter.beforeEach(toLocation, fromLocation);
    return () => browserRouter.afterEach();
  }, [fromLocation, toLocation]);

  return <Skeleton active />;
};

export function LoadModule({ path }) {
  if (!path) {
    return <Navigate to="/404" replace />;
  }

  return <Suspense fallback={<SpinFallback />}>{React.createElement(lazyImport(`pages${path}`))}</Suspense>;
}
LoadModule.propTypes = {
  path: PropTypes.string.isRequired,
};

export const commonRoutes = [
  { path: "/login", element: <LoadModule path="/login" />, errorElement: <ErrorPage />, handle: { title: "登录" } },
  { path: "*", element: <NotFound /> },
  { ...layoutRouter, children: [{ index: true, element: <LoadModule path="/index" />, errorElement: <ErrorPage /> }] },
];

export const dynamicRoutes = [{ path: "/file/*", element: <LoadModule path="/file" /> }];

const createDynamicRouter = (routers) => {
  return routers.map((router) => {
    const { component, children, handle, meta } = router;
    // 注入 meta ===> 获取 useMatches
    router.handle = handle || meta;
    router.errorElement = router.errorElement || <ErrorPage />;

    if (component && component.toLocaleLowerCase() === ROUTER_CATALOG_COMPONENT) {
      router.element = <Outlet />;
      router.children = createDynamicRouter(children);
    } else if (component && children && children.length) {
      router.element = <Outlet />;
      router.children = [{ index: true, element: <LoadModule path={component} /> }];
      router.children.push(...createDynamicRouter(children));
    } else if (component && !children) {
      router.element = <LoadModule path={component} />;
    }
    return router;
  });
};

const browserRouter = new BrowserRouter({
  routes: commonRoutes,
});

// 重写addRoutes方法
const originalAddRoutes = BrowserRouter.prototype.addRoutes;
BrowserRouter.prototype.addRoutes = function (values, ...arg) {
  if (Array.isArray(values)) {
    values = createDynamicRouter(values);
  } else if (values.children && values.children.length) {
    values.children = createDynamicRouter(values.children);
  }
  return originalAddRoutes.call(this, values, ...arg);
};

export default browserRouter;
